home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-12-27 | 6.2 KB | 229 lines | [TEXT/PJMM] |
- Unit TPopUpMenu;
-
- { ⌐1986-1989 Bill Stackhouse }
- { Stackhouse Software }
- { Natick, MA 01760 }
-
- Interface
-
- {$IFC UNDEFINED UsePopUpMenu}
- {$SETC UsePopUpMenu = FALSE}
- {$ENDC}
- {$IFC UsePopUpMenu}
-
- Uses
- TObject;
-
- Const
- maxPopUps = 15;
-
- Type
- TPopUpMenu = Object(TObject)
- numPopGroups: 0..maxPopUps; {number of popup menus}
- callBackProc: ProcPtr; {who to call back after menu used}
- PopGroup: Array[1..maxPopUps] Of Record
- menu: MenuHandle; {handle to menu}
- resNum: Integer; {resource number of menu}
- static: Integer; {item number of related static text}
- nowOn: Integer; {which item in menu is current}
- popUpBox: Rect; {rectangle for popup box, computed}
- promptBox: Rect; {static text box outline}
- itemText: Str255; {text of current item}
- End;
- Procedure TPopUpMenu.Init;
- Procedure TPopUpMenu.Add (pMenu: MenuHandle; {}
- pMenuRes: Integer; {}
- pStatic: Integer; {}
- pNowOn: Integer); {}
- Procedure TPopUpMenu.Revise (curDialog: DialogPtr);
- Procedure TPopUpMenu.Draw (i: Integer);
- Procedure TPopUpMenu.DrawAll;
- Procedure TPopUpMenu.Mouse (theEvent: EventRecord);
- Procedure TPopUpMenu.Get (theGroup: Integer;
- Var theItem: Integer;
- Var theText: Str255);
- Function TPopUpMenu.Error: Integer;
- Procedure TPopUpMenu.CallBack (theCallBack: ProcPtr);
- End;
-
- {$ENDC}
-
- Implementation
-
- {$IFC UsePopUpMenu}
-
- Const
- DialogGroupIgnored = -10; {too many groups, key, menus, or user items were added}
-
- Var
- globalError: Integer;
-
- Procedure UserAction (proc: ProcPtr);
- Inline
- $205f, {movea.l (a7)+,a0 ; (a0) is a ptr to string, 4(a0) is mode}
- $4e90;
-
- Procedure TPopUpMenu.Init;
- Begin
- globalError := noErr;
- SELF.numPopGroups := 0;
- SELF.callBackProc := Nil;
- End; {TPopUpMenu.Init}
-
- Procedure TPopUpMenu.Add (pMenu: MenuHandle; {}
- pMenuRes: Integer; {}
- pStatic: Integer; {}
- pNowOn: Integer); {}
- Var
- i: Integer;
- Begin
- globalError := noErr;
- With SELF Do
- If numPopGroups < maxPopUps Then
- Begin
- numPopGroups := numPopGroups + 1;
- With PopGroup[numPopGroups] Do
- Begin
- menu := pMenu;
- resNum := pMenuRes;
- static := pStatic;
- nowOn := pNowOn;
- SetRect(popUpBox, 0, 0, 0, 0);
- SetRect(promptBox, 0, 0, 0, 0);
- If menu = Nil Then
- menu := GetMenu(resNum);
- For i := 1 To CountMItems(menu) Do
- SetItemMark(menu, i, ' ');
- SetItemMark(menu, nowOn, CHR(checkMark));
- End;
- End
- Else
- globalError := DialogGroupIgnored;
- End; {TPopUpMenu.Add}
-
- Procedure TPopUpMenu.Draw;
- Const
- leftSlop = 13; {leave this much space on left of title}
- botSlop = 5; {this much below baseline}
- Begin
- globalError := noErr;
- With SELF.popGroup[i] Do
- Begin
- EraseRect(popUpBox);
- With promptBox Do
- SetRect(popUpBox, right + 1, top, right + menu^^.menuWidth + 1, bottom + 2); {l,t,r,b}
- FrameRect(popUpBox);
- With popUpBox Do
- Begin
- MoveTo(right, top + 2);
- LineTo(right, bottom);
- LineTo(left + 2, bottom);
- MoveTo(left + LeftSlop, bottom - BotSlop);
- GetItem(menu, nowOn, itemText);
- DrawString(itemText);
- End;
- End;
- End; {TPopUpMenu.Draw}
-
- Procedure TPopUpMenu.DrawAll;
- Var
- i: Integer;
- Begin
- globalError := noErr;
- For i := 1 To SELF.numPopGroups Do
- SELF.Draw(i);
- End; {TPopUpMenu.DrawAll}
-
- Procedure TPopUpMenu.Revise (curDialog: DialogPtr);
- Var
- i: Integer;
- curFont, curFontSize: Integer;
- fontData: FontInfo;
- theType: Integer;
- theHandle: Handle;
- theBox: Rect;
- Begin
- globalError := noErr;
- With SELF Do
- For i := 1 To numPopGroups Do
- With popGroup[i] Do
- Begin
- curFont := thePort^.txFont;
- curFontSize := thePort^.txSize;
- TextFont(SystemFont);
- TextSize(12);
- GetFontInfo(fontData);
- TextFont(curFont);
- TextSize(curFontSize);
- GetDItem(curDialog, static, theType, theHandle, promptBox);
- With promptBox, fontData Do
- SetRect(promptBox, left, top, right, top + ascent + descent + leading); {l,t,r,b}
- SetDItem(curDialog, static, theType, theHandle, promptBox);
- End;
- End; {TPopUpMenu.Revise}
-
- Procedure TPopUpMenu.Mouse (theEvent: EventRecord);
- Var
- i: Integer;
- popLoc: Point;
- chosen: Longint;
- newChoice: Integer;
- Begin
- globalError := noErr;
- GlobalToLocal(theEvent.where); {because PtInRect wants it that way}
- With theEvent, SELF Do
- Begin
- If numPopGroups > 0 Then
- For i := 1 To numPopGroups Do
- If PtInRect(theEvent.where, PopGroup[i].popUpBox) Then
- With PopGroup[i] Do
- Begin
- InvertRect(promptBox); {hilight the prompt}
- InsertMenu(menu, -1); {insert our menu in the menu list}
- popLoc := popUpBox.topLeft; {copy our item╒s topleft}
- LocalToGlobal(popLoc); {convert back to global coords}
- CalcMenuSize(menu); {Work around Menu Mgr bug}
- With popLoc Do
- chosen := PopUpMenuSelect(menu, v, h, nowOn);
- InvertRect(promptBox); {unhilight the prompt}
- DeleteMenu(resNum); {remove our menu from the menu list}
- If chosen <> 0 Then
- Begin
- newChoice := LoWord(chosen); {get the chosen item number}
- If newChoice <> nowOn Then
- Begin
- SetItemMark(menu, nowOn, ' '); {unmark the old choice}
- SetItemMark(menu, newChoice, CHR(checkMark)); {mark the new choice}
- nowOn := newChoice; {update the current choice}
- SELF.Draw(i);
- If callBackProc <> Nil Then
- UserAction(callBackProc); {let them play around}
- End;
- Leave;
- End; {With}
- End;
- End;
- End; {TPopUpMenu.Mouse}
-
- Procedure TPopUpMenu.Get (theGroup: Integer;
- Var theItem: Integer;
- Var theText: Str255);
- Begin
- globalError := noErr;
- theItem := SELF.PopGroup[theGroup].nowOn;
- theText := SELF.PopGroup[theGroup].itemText;
- End; {TPopUpMenu.GetNowOn}
-
- Function TPopUpMenu.Error: Integer;
- Begin
- Error := globalError;
- End; {TPopUpMenu.Error}
-
- Procedure TPopUpMenu.CallBack (theCallBack: ProcPtr);
- Begin
- SELF.callBackProc := theCallBack;
- End; {TPopUpMenu.CallBack}
-
- {$ENDC}
-
- End.